<template>
    <div class="page-container">
        <div :class="{searchContainer:search.options && search.options.length>0}" v-if="config.search.show">
            <json-form 
                :direction="search.direction"
                :form="search.form"
                :labelPosition="search.labelPosition"
                ref="search"
                :options="search.options"
				v-bind="search?.attrs">
				<template :slot="item.slot" v-for="item in searchSlots">
					<slot :name="item.slot"></slot>
				</template>
			</json-form>
        </div>
        <div v-if="config.operation.show">
            <json-form
                :direction="operation.direction"
                :form="operation.form"
                ref="operation"
                :options="operation.options"
				v-bind="operation?.attrs">
				<template :slot="item.slot" v-for="item in operationSlots">
					<slot :name="item.slot"></slot>
				</template>
			</json-form>
        </div>
        <div>
            <el-table 
                :data="tableData"
				:height="tableHeight"
                header-row-class-name="cust-head"
                header-cell-class-name="cust-head-cell"
				:row-class-name="tableRowClassName"
				v-bind="props"
				v-if="config.table.show"
				@selection-change="handleSelectionChange"
                >
				<el-table-column
					type="selection"
					width="55"
					v-if="config.table.checkbox"
					>
				</el-table-column>
                <el-table-column 
                    v-for="item in columns" 
                    :key="item.key" 
                    :prop="item.key" 
                    :label="item.label" 
                    :width="item.width"
                    :align="item.align?item.align:'center'"
					v-bind="item.props?item.props:{}"
                    >
					<template slot="header" slot-scope="scope">
						<span v-if="!item.headerSlot">{{item.label}}</span>
						<slot :name="item.headerSlot" v-bind:data="scope" v-else></slot>
					
					</template>
                    <template slot-scope="scope">
                            <div v-if="item.slot=='operation'">
								<slot name="moreoperation" :data="scope"></slot>
                                <el-button type="primary" v-if="item?.editBtn?.show"  v-permission="item?.editBtn?.permission" size="small" @click="edit(scope.row)">编辑</el-button>
                                <el-button type="danger" v-if="item?.removeBtn?.show" v-permission="item?.removeBtn?.permission" size="small" @click="delUser(scope.row)">删除</el-button>
							</div>
							<slot :name="item.slot" v-else-if="item.slot" v-bind:data="scope"></slot>
							<template v-else>
								{{scope.row[item.key]}}
							</template>
                    </template>
                    
                </el-table-column>
            </el-table>
        </div>
		<div style="text-align:right;margin-top:10px;" v-if="config.pagination.show">
			<el-pagination
				background
				layout="total,sizes,prev,pager,next"
				:page-size="pageSize"
				:page-sizes="[10,20,50,100]"
				:total="pageTotal"
				:current-page="pageNum"
				@next-click="page(1)"
				@prev-click="page(-1)"
				@current-change="pageChange"
				@size-change="sizeChange"
				></el-pagination>
		</div>
        <div>
            <el-dialog 
				:title="mode=='add'?'新增':'修改'" 
				v-model="show"
				v-bind="config.dialog"
				:visible.sync="show"
				:close-on-click-modal="false"
				>

                <json-form
                    :direction="updateField.direction"
                    :form="updateField.form"
                    ref="updateForm"
                    :options="updateField.options"
					v-bind="updateField?.attrs"
					v-if="show"
					>
					<template :slot="item.slot" v-for="item in updateFiledSlots" slot-scope="scope">
						<slot :name="item.slot" :data="scope.data"></slot>
					</template>
                </json-form>
                <span slot="footer">
                    <el-button @click="show=false">取消</el-button>
                    <el-button type="primary" @click="dialogConfirm">确认</el-button>
                </span>
            </el-dialog>
            <!-- <component v-else :is="customComp && show" :data="updateField">

            </component> -->
        </div>
    </div>
</template>
<script>
import request from "@/requests"
import jsonForm from "./json-form.vue"
import bus from "@/util/bus"
import { deepMerge } from "@/util/merge"
import {cloneDeep} from "lodash-es"
export default {
	name:"page-table",
	props:{
		func:{
			type:Function,
			default:()=>{}
		},
		autosearch:{
			type:Boolean,
			default:true,
		},
		custComp:{},
		props:{
			type:Object,
			default:()=>({})
		}
	},
	components:{
		jsonForm
	},
	data(){
		return {
			columns:[],
			reqOptions:{},
			search:{},
			operation:{},
			tableData:[],
			show:false,
			updateField:{},
			pageTotal:1,
			pageSize:10,
			pageNum:1,
			tableHeight:350,
			mode:"add",
			checkboxSelected:[],
			config:{
				dialog:{},
				operation:{
					show:true
				},
				table:{
					autoHeight:true,
					show:true,
					checkbox:false
				},
				pagination:{
					pageSize:100,
					show:true
				},
				search:{
					show:true
				}
			},
		}
	},
	async created(){
		let options = await this.func(this)
		//ui配置
		let config = cloneDeep(this.config)
		deepMerge(config,cloneDeep(options.config))
		this.config = config
		this.pageSize = this.config.pagination.pageSize
		//其他
		this.columns = options.columns || []
		this.reqOptions = options.reqOptions || {}
		this.search = options.search || {}
		this.operation = options.operation || {}
		this.updateFieldMethod = options.updateField || (()=>{})
		this.addFieldMethod = options.addField || options.updateField || (()=>{})
		this.getList()
	},
	methods:{
		tableRowClassName({row, rowIndex}) {
        if (row.priority === 2) {
          return 'warning-row';
        } else if (rowIndex === 3) {
          
        }
        return '';
      },
		getList(){
			let params = {
				pageNum:this.pageNum,
				pageSize:this.pageSize,
				...this.search.form
			}
			let list = this.reqOptions.list
			if(!list){
				console.warn("未配置reqOptions.list")
				return
			}
			if(list?.custom){
				list.custom.callback(params)
				return
			}
			console.log([list.method])
			request[list.method](list.url,{params}).then(res=>{
				this.tableData = res.data.list
				this.pageTotal = res.data.total
				list.callback && list.callback(this,res)
				if(res.data.pages < this.pageNum && res.data.pages != 0){
					this.pageNum = res.data.pages
					this.getList()
				}
				
			})
		},
		searchFun(callback){
			console.log(this)
			this.$refs.search.submit((form)=>{
				console.log("验证成功",form)
				callback && callback instanceof Function && callback(form)
			})
		},
		async addFun(){
			this.updateField =await this.addFieldMethod()
			this.show = true
			this.mode = "add"
            
		},
		async edit(row){
			this.$store.dispatch("changeLoading",true)
			this.updateField =await this.updateFieldMethod()
			console.log(row)
			this.updateField.form = row
			this.show = true
			this.mode = "edit"
			this.$store.dispatch("changeLoading",false)
		},
		addForm(res){
			let insert = this.reqOptions.insert
			if(insert?.custom){
				insert.custom.callback(res)
				return
			}
			if(!insert){
				console.warn("未配置reqOptions.insert")
				return
			}
			if(insert?.custom){
				insert.custom.callback(res)
				return
			}
			request[insert.method](insert.url,res).then(res=>{
				console.log("插入---",res)
				if(res.data){
					this.show = false
					insert.callback && insert.callback(this,res)
					this.getList()
				}
				
			})
		},
		updateForm(res){
			let update = this.reqOptions.update
			if(update?.custom){
				update.custom.callback(res)
				return
			}
			if(!update){
				console.warn("未配置reqOptions.update")
				return
			}
			if(update?.custom){
				update.custom.callback(res)
				return
			}
			request[update.method](update.url,res).then(res=>{
				if(res.data){
					this.show = false
					update.callback && update.callback(this,res)
					this.getList()
				}
			})
		},
		dialogConfirm(){
			console.log("提交")
			this.$refs.updateForm.submit((res)=>{
				console.log("提交",res)
				//
				if(this.mode == "add"){
					this.addForm(res)
				}else{
					this.updateForm(res)
				}
			})
		},
		async delUser(row){
			this.$confirm("确定删除吗？","删除",{
				confirmButtonText:"确定",
				cancelButtonText:"取消",
				type:"warning"
			}).then(()=>{
				console.log(row.id)
				let remove = this.reqOptions.remove
				if(remove?.custom){
					remove.custom.callback(row)
					return
				}
				if(!remove){
					console.warn("未配置reqOptions.remove")
					return
				}
				if(remove?.custom){
					remove.custom.callback(row)
					return
				}
				request[remove.method](remove.url.replace("${id}",row.id)).then(res=>{
					console.log(res)
					remove.callback && remove.callback(this,res)
					this.getList()
				})
			})
			
		},
		page(num){
			console.log("page")
			if(this.pageNum+num <= this.pageTotal && this.pageNum+num != 0){
				this.pageNum += num
				this.getList()
			}
		},
		pageChange(num){
			this.pageNum = num
			this.getList()
		},
		sizeChange(num){
			this.pageSize = num
			this.pageNum = 1
			this.getList()
		},
		resize(){
			// 计算el-table的最大高度
			setTimeout(()=>{
				if(this.config.table.autoHeight){
					console.log("tableHeight 为true")
					this.tableHeight = window.innerHeight - 80 - this.$refs.search.$el.clientHeight - this.$refs.operation.$el.clientHeight -42 -125
				}else{
					this.tableHeight = ""
					console.log("tableHeight 为false",this.tableHeight)
				}
			})
		},
		async updateData(form={}){
			let tform = this.updateField.form
			let formKeys = Object.keys(form)
			if(formKeys.some(item=>tform.hasOwnProperty(item)) || Object.keys(tform).length == 0 || this.mode == "add"){
				console.log("update",this.updateField,this.$parent)
				this.updateField =await this.updateFieldMethod({...this.updateField.form,...form})
			}else{
				console.log("不更新")
			}
			
		},
		handleSelectionChange(val){
			this.checkboxSelected = val
			this.$emit("selectChange",val)
		},
		// 删除选中的
		batchDel(){
			let batch = this.reqOptions.batch
			if(!batch){
				console.warn("未配置reqOptions.batch")
				return
			}
			if(batch?.custom){
				let selected = this.checkboxSelected
				batch.custom.callback(selected)
				return
			}
			this.$confirm("将删除选中的行,是否继续?","删除",{
				confirmButtonText:"确定",
				cancelButtonText:"取消",
				type:"warning"
			}).then(()=>{
				
				let ids = selected.map(item=>item.id)
				request[batch.method](batch.url,{ids}).then(res=>{
					this.getList()
				})
			})
			
		}
	},

	mounted(){
		console.log(this.$refs.search)
		this.resize()
		window.addEventListener("resize",this.resize)
		bus.$on("updateData",this.updateData)
	},
	beforeDestroy(){
		window.removeEventListener("resize",this.resize)
		bus.$off("updateData",this.updateData)
	},
	computed:{
		// 计算search 插槽
		searchSlots(){
			return this.search?.options?.filter(item=>item.slot)
		},
		//operation 插槽
		operationSlots(){
			return this.operation?.options?.filter(item=>item.slot)
		},
		updateFiledSlots(){
			return this.updateField?.options?.filter(item=>item.slot)
		}
	},
	watch:{
		config(){
			this.resize()
		}
	}
}
</script>
<style scoped lang="less">
/deep/ .cust-head{
    .cust-head-cell{
    background-color: #F2F6FC;

    }
}
.page-container{
    display: flex;
    flex-direction: column;
}
//设置dialog可滚动

/deep/ .el-dialog__body{
	max-height: 60vh;
	overflow: auto;
}
.searchContainer{
	border-bottom: 1px solid #eee;
	margin-bottom: 22px;
}
</style>
<style>
  .el-table .warning-row {
    background: #ffd483;
  }

  .el-table .success-row {
    background: #f0f9eb;
  }
</style>